﻿using System;
using System.Collections.Generic;
using System.Windows.Forms;

namespace RoboRally
{
	/// <summary>
	/// The main window.
	/// </summary>
	public partial class MainWindow : Form, IUserDisplay
	{
		private readonly List<PlayerStatus> playerStats = new List<PlayerStatus>();

		/// <summary>
		/// Create the window.
		/// </summary>
		public MainWindow()
		{
			InitializeComponent();

			// initialize engine
			Engine = new Engine(this);

			UpdateMenu();
		}

		/// <summary>
		/// The engine that operates the game.
		/// </summary>
		internal Engine Engine { get; private set; }

		/// <summary>
		/// The play button was clicked.
		/// </summary>
		private void Play_Click(object sender, EventArgs e)
		{
			Engine.Play();
			UpdateMenu();
		}

		/// <summary>
		/// The pause button was clicked.
		/// </summary>
		private void Pause_Click(object sender, EventArgs e)
		{
			Engine.Pause();
			UpdateMenu();
		}

		/// <summary>
		/// The stop button was clicked.
		/// </summary>
		private void Stop_Click(object sender, EventArgs e)
		{
			if (MessageBox.Show(this, "Do you want to end this run?", "RoboRally", MessageBoxButtons.YesNo) != DialogResult.Yes)
				return;
			Engine.Stop();
			UpdateMenu();
		}

		/// <summary>
		/// Update the main window menu.
		/// </summary>
		public void UpdateMenu()
		{
			toolStripButtonPlay.Enabled = Engine.Mode != Engine.MODE.PLAY;
			toolStripButtonPause.Enabled = Engine.Mode == Engine.MODE.PLAY;
			toolStripButtonStop.Enabled = Engine.Mode != Engine.MODE.STOP;
		}

		/// <summary>
		/// Got a close window event. Ask for confirmation if a game is in process.
		/// </summary>
		private void GameDisplay_FormClosing(object sender, FormClosingEventArgs fcea)
		{
			if ((Engine.Mode != Engine.MODE.STOP) && (MessageBox.Show(this, "Do you want to close the game?", "Broadside", MessageBoxButtons.YesNo) != DialogResult.Yes))
				fcea.Cancel = true;
		}

		/// <summary>
		/// Starting a game.
		/// </summary>
		public void SetupGame()
		{

			// if have stats windows - dispose them
			while (playerStats.Count > 0)
			{
				PlayerStatus statOn = playerStats[0];
				playerStats.RemoveAt(0);
				panelPlayers.Controls.Remove(statOn);
				statOn.Dispose();
			}

			// create player stats windows
			int top = 0;
			int winOn = 0;
			foreach (PlayerInternal playerOn in Engine.Players)
			{
				PlayerStatus ps = new PlayerStatus(playerOn) {Width = panelPlayers.Width / 2};
				if ((winOn & 1) == 0)
				{
					ps.Top = top;
					ps.Left = 0;
				}
				else
				{
					ps.Top = top;
					ps.Left = panelPlayers.Width / 2;
					top += ps.Height;
				}
				winOn++;
				playerStats.Add(ps);
				panelPlayers.Controls.Add(ps);
			}
	
			// set panel height to match
			panelPlayers.Height = top;

			UpdateMap();
			UpdatePlayers();
		}

		/// <summary>
		/// Update the map window.
		/// </summary>
		public void UpdateMap()
		{
			mapDisplay1.Invalidate();
			mapDisplay1.Update();
		}

		/// <summary>
		/// Update (re-draw) the player status windows.
		/// </summary>
		public void UpdatePlayers()
		{

			if (playerStats.Count == 0)
				return;

			foreach (PlayerStatus ps in playerStats)
				ps.UpdateStats();
			panelPlayers.Invalidate();
			panelPlayers.Update();
		}

		/// <summary>
		/// Adds a message to the status window.
		/// </summary>
		/// <param name="message">The message to add.</param>
		public void StatusMessage(string message)
		{
			listBoxStatus.Items.Add(message);
			listBoxStatus.TopIndex = listBoxStatus.Items.Count - 1;
		}

		/// <summary>
		/// Set the turn or phase number increases.
		/// </summary>
		/// <param name="turn">The turn number.</param>
		/// <param name="phase">The phase number.</param>
		public void TurnNumber(int turn, int phase)
		{
			labelTurn.Text = string.Format("Turn: {0}, Phase {1}", turn, phase);
		}
	}
}
